/*
 * Copyright 2002-2018 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.yb.client.controller;

import com.yb.client.feign.ResourceFeignClient;
import com.yb.core.enums.MediaFilesEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.web.WebAttributes;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.HtmlUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Map;

/**
 * OAuth2 Log in controller.
 *
 * @author Joe Grandja
 * @author Rob Winch
 */
@Controller
@Slf4j
public class OAuth2LoginController {

	@Autowired
	RestTemplate restTemplate;

	@Autowired
	ResourceFeignClient feignClient;

	@GetMapping("/")
	public String index(Model model, @RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient authorizedClient,
			@AuthenticationPrincipal OAuth2User oauth2User,Authentication authentication) {
		log.error("OAuth2LoginController authentication:{}",authentication);
		model.addAttribute("userName", oauth2User.getName());
		model.addAttribute("clientName", authorizedClient.getClientRegistration().getClientName());
		model.addAttribute("userAttributes", oauth2User.getAttributes());
		return "index";
	}


	@RequestMapping(value = "/resourses",produces = MediaType.TEXT_PLAIN_VALUE)
	@ResponseBody
	public String resource(@RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient authorizedClient,
						   @AuthenticationPrincipal OAuth2User oauth2User, Authentication authentication){
//		HttpHeaders httpHeaders = new HttpHeaders();
//		httpHeaders.add("Authorization","Bearer "+authorizedClient.getAccessToken().getTokenValue());
//		HttpEntity<Object> objectHttpEntity = new HttpEntity<>(httpHeaders);
//		ResponseEntity<String> entity = restTemplate.exchange("http://localhost:8081/", HttpMethod.GET,objectHttpEntity, String.class);
//		System.out.println("entity:"+entity);
		log.error(" OAuth2LoginController authentication = {}",authentication);
		String result = feignClient.get();

		return result;
	}

	@RequestMapping(value = "/hello",produces = MediaType.TEXT_PLAIN_VALUE)
	@ResponseBody
	public String hello(@RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient authorizedClient,
						   @AuthenticationPrincipal OAuth2User oauth2User, Authentication authentication){
//		HttpHeaders httpHeaders = new HttpHeaders();
//		httpHeaders.add("Authorization","Bearer "+authorizedClient.getAccessToken().getTokenValue());
//		HttpEntity<Object> objectHttpEntity = new HttpEntity<>(httpHeaders);
//		ResponseEntity<String> entity = restTemplate.exchange("http://localhost:8081/", HttpMethod.GET,objectHttpEntity, String.class);
//		System.out.println("entity:"+entity);
		log.error(" OAuth2LoginController authentication = {}",authentication);
		String result = feignClient.hello();

		return result;
	}

	@RequestMapping(value = "/admin",produces = MediaType.TEXT_PLAIN_VALUE)
	@ResponseBody
	public String admin(@RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient authorizedClient,
						@AuthenticationPrincipal OAuth2User oauth2User, Authentication authentication){
//		HttpHeaders httpHeaders = new HttpHeaders();
//		httpHeaders.add("Authorization","Bearer "+authorizedClient.getAccessToken().getTokenValue());
//		HttpEntity<Object> objectHttpEntity = new HttpEntity<>(httpHeaders);
//		ResponseEntity<String> entity = restTemplate.exchange("http://localhost:8081/", HttpMethod.GET,objectHttpEntity, String.class);
//		System.out.println("entity:"+entity);
		log.error(" OAuth2LoginController authentication = {}",authentication);
		String result = feignClient.admin();

		return result;
	}
	@RequestMapping("/login.html")
	@ResponseBody
	public String loginPage(HttpServletRequest request){
		return generateLoginPageHtml(request,false,true);
	}

	private String generateLoginPageHtml(HttpServletRequest request, boolean loginError, boolean logoutSuccess) {
		String errorMsg = "Invalid credentials";
		if (loginError) {
			HttpSession session = request.getSession(false);
			if (session != null) {
				AuthenticationException ex = (AuthenticationException) session
						.getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
				errorMsg = (ex != null) ? ex.getMessage() : "Invalid credentials";
			}
		}
		String contextPath = request.getContextPath();
		StringBuilder sb = new StringBuilder();
		sb.append("<!DOCTYPE html>\n");
		sb.append("<html lang=\"en\">\n");
		sb.append("  <head>\n");
		sb.append("    <meta charset=\"utf-8\">\n");
		sb.append("    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n");
		sb.append("    <meta name=\"description\" content=\"\">\n");
		sb.append("    <meta name=\"author\" content=\"\">\n");
		sb.append("    <title>Please sign in</title>\n");
		sb.append("  </head>\n");
		sb.append("  <body>\n");
		sb.append("     <div class=\"container\">\n");

			sb.append("<h2 class=\"form-signin-heading\">Login with OAuth 2.0</h2>");
			sb.append(createError(loginError, errorMsg));
			sb.append(createLogoutSuccess(logoutSuccess));
			sb.append("<table class=\"table table-striped\">\n");
			sb.append(" <tr><td>");
			sb.append("<a href=\"").append(contextPath).append("/oauth2/authorization/login-client").append("\">");
			sb.append("login-client");
			sb.append("</a>");
			sb.append("</td></tr>\n");
			sb.append("</table>\n");

			sb.append("</table>\n");
		sb.append("</div>\n");
		sb.append("</body></html>");
		return sb.toString();
	}
	private static String createError(boolean isError, String message) {
		if (!isError) {
			return "";
		}
		return "<div class=\"alert alert-danger\" role=\"alert\">" + HtmlUtils.htmlEscape(message) + "</div>";
	}

	private static String createLogoutSuccess(boolean isLogoutSuccess) {
		if (!isLogoutSuccess) {
			return "";
		}
		return "<div class=\"alert alert-success\" role=\"alert\">You have been signed out</div>";
	}
}
